home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / DSHJ2 / FASTROT.SSS < prev    next >
Encoding:
Text File  |  2001-02-10  |  11.0 KB  |  593 lines

  1. *
  2. *
  3. *   Rotate 90 degrees clockwise a large rectangular page-size form in place
  4. *   where the DST form width is less than the SRC form
  5. *
  6. *   Programmer: Dave Staugas
  7. *         Date: 9-June-89
  8. *
  9. *
  10. *   Paper size data:                    Timings (secs):
  11. *                    Temp buf size:   5k  10k  20k  40k
  12. *     Port_width   Land_width   Rectangle excess  d2= 1    2    4    8
  13. *     ----------   ----------   ----------------
  14. *  Letter  300        398       98             56   35   25   20
  15. *  Legal   300        510       210            123   71   45   32
  16. *  A4       292        424       132             72   43   29   22
  17. *  B5       252        366       114             47   30   20   16
  18. *
  19. *
  20.     .globl    roto
  21.     .globl    recrot
  22. *
  23. *
  24. *   Entry:
  25. *
  26. *   a0   -> base address of landscape form to rotate
  27. *   a1   -> temp buffer allocated in multiples of (16 * DST form-width)
  28. *   d0.w =  SRC form-width in bytes (must be even)
  29. *   d1.w =  DST form-width in bytes (must be even)
  30. *   d2.w =  # of (16 * DST form-width) multiples that can be used in temp buffer
  31. *
  32. *   Exit:
  33. *
  34. *   all registers preserved, rectangular form is rotated in place
  35. *        90 degrees clockwise with new (DST) form-width
  36. *
  37. recrot:
  38.     movem.l    a0-a6/d0-d7,-(sp)
  39. *
  40. *  1st rotate largest chunk (a square) in place
  41. *
  42.     move.w    d1,d4        ;do a square rotate 1st
  43.     bsr    roto        ;rotate the biggest chunk in place
  44. *
  45. *  Now rotate-copy d2.w vertical columns of tiles to temp buffer
  46. *
  47.     move.l    a1,a5        ;save temp buf ptr in a5
  48.     lea    (a0,d1.w),a2    ;a2-> SRC top tile of column just rite of square
  49.     lea    -2(a1,d1.w),a3    ;a3-> DST top/rightmost tile of temp buf
  50. schlp:
  51.     move.w    d0,d7        ;d0 = SRC wrap
  52.     lsl.w    #4,d7        ;d7 = SRC tile wrap
  53. *
  54.     move.w    d1,d6        ;d1 = DST wrap
  55.     lsl.w    #4,d6        ;d6 = DST tile wrap
  56. *
  57.     move.l    a2,a4        ;save a2 for later
  58.     move.w    d1,d4        ;DST width
  59.     lsr.w    #1,d4
  60.     subq.w    #1,d4        ;d4 = # of tiles in column (-1)
  61.     subq.w    #1,d2        ;d2 = # of columns (-1)
  62. buflp0:
  63.     movem.l    a2-a3/d2/d4/d6,-(sp)
  64. buflp:
  65.     move.l    a2,a1
  66.     move.l    a3,a6
  67.     bsr    rot2tile
  68.     adda.w    d7,a2
  69.     subq.l    #2,a3    
  70.     dbra    d4,buflp
  71.  
  72.     movem.l    (sp)+,a2-a3/d2/d4/d6
  73.     addq.l    #2,a2
  74.     adda.w    d6,a3
  75.     dbra    d2,buflp0
  76. *
  77.     move.l    8(sp),d2    ;restore buffer size multiple
  78.     add.w    d2,d2        ;  in words
  79. *
  80. *   buffer is full, now scrunch the big form (decrease SRC width by d2*2 bytes)
  81. *
  82.     move.l    a4,a3        ;1st DST column just right of big square
  83.     lea    (a3,d2.w),a2    ;1st SRC column just right of copied columns
  84.     move.w    d1,d4
  85.     lsl.w    #3,d4        ;DST width *8 is # of rows
  86.     move.w    d4,d7
  87.     subq.w    #2,d7
  88. *
  89.     sub.w    d2,d0        ;new SRC width (it's shrinking)
  90.     move.w    d0,d4
  91.     lsr.w    #2,d4        ;get # of long words in SRC row
  92.     bcc.s    elong        ;br if integral # of longwords
  93. *
  94. *   else, do one short word 1st..
  95. *
  96. rwlp0:
  97.     move.w    d4,d5
  98.     move.w    (a2)+,(a3)+
  99.     bra.s    rwlp1i
  100. rwlp1:
  101.     move.l    (a2)+,(a3)+
  102. rwlp1i:
  103.     dbra    d5,rwlp1
  104.     adda.w    d2,a2
  105.     dbra    d7,rwlp0
  106.     bra.s    rwdone
  107. elong:    
  108.     move.w    d4,d5
  109.     bra.s    rwlp2i
  110. rwlp2:
  111.     move.l    (a2)+,(a3)+
  112. rwlp2i:
  113.     dbra    d5,rwlp2
  114.     adda.w    d2,a2
  115.     dbra    d7,elong
  116. rwdone:
  117.     move.w    d0,d7
  118.     sub.w    d1,d7
  119.     lsr.w    #1,d7
  120.     bra    rwlp5i            ;gotta get special case
  121. rwlp5:
  122.     move.w    (a2)+,(a3)+        ;copied for inner column difference
  123. rwlp5i:
  124.     dbra    d7,rwlp5
  125. *
  126. *
  127.     move.w    d1,d6        ;d1 = DST wrap
  128.     lsl.w    #4,d6        ;d6 = DST tile wrap
  129. *
  130. scrnchlp:
  131.     lea    (a0,d0.w),a2    ;a2-> SRC top tile column at far right 
  132.     lea    -2(a3,d1.w),a3    ;a3-> DST rightmost tile of space just freed
  133. *
  134.     move.w    d0,d7        ;d0 = SRC wrap
  135.     lsl.w    #4,d7        ;d7 = tile wrap
  136. *
  137.     sub.w    d2,d0        ;new SRC width (it's shrinking)
  138.     cmp.w    d1,d0        ;did we go too far?
  139.     bpl.s    .10        ;br if ok
  140. *
  141.     move.w    d1,d3
  142.     sub.w    d0,d3        ;d3 = # of word-columns not to do
  143.     sub.w    d3,d2        ;d2 = # of word-columns to do
  144.     add.w    d3,d0
  145.     lsr.w    #1,d3        ;d2 = # of columns not done this trip
  146.     mulu    d6,d3
  147.     add.l    d3,a3        ;adjust DST ptr
  148. .10:
  149.     add.w    d2,d0
  150.     suba.w    d2,a2        ;adjust SRC ptr
  151. *
  152.     move.l    a2,a4        ;save a2 for later
  153.     move.w    d1,d4        ;DST width
  154.     lsr.w    #1,d4
  155.     subq.w    #1,d4        ;d4 = # of tiles in column (-1)
  156.     move.w    d2,-(sp)
  157.     lsr.w    #1,d2
  158.     subq.w    #1,d2        ;d2 = # of columns (-1)
  159. bufloop0:
  160.     movem.l    a2-a3/d2/d4/d6,-(sp)
  161. bufloop:
  162.     move.l    a2,a1
  163.     move.l    a3,a6
  164.     bsr    rot2tile
  165.     adda.w    d7,a2
  166.     subq.l    #2,a3    
  167.     dbra    d4,bufloop
  168. *
  169.     movem.l    (sp)+,a2-a3/d2/d4/d6
  170.     addq.l    #2,a2
  171.     adda.w    d6,a3
  172.     dbra    d2,bufloop0
  173. *
  174.     move.w    (sp)+,d2
  175. *
  176. *   now scrunch the big form (decrease SRC width by d2 bytes)
  177. *
  178.     sub.w    d2,d0
  179.     move.l    a4,a3        ;1st DST to holding buffer
  180.     lea    (a3,d2.w),a2    ;1st SRC column just right of big square
  181.     move.w    d1,d4
  182.     lsl.w    #3,d4        ;DST width *8 is # of rows
  183.     move.w    d4,d7
  184.     subq.w    #2,d7
  185. *
  186.     move.w    d0,d4
  187.     lsr.w    #2,d4        ;get # of long words in SRC row
  188.     bcc.s    evnlong        ;br if integral # of longwords
  189. *
  190. *   else, do one short word 1st..
  191. *
  192. rowlp0:
  193.     move.w    d4,d5
  194.     move.w    (a2)+,(a3)+
  195.     bra.s    rowlp1i
  196. rowlp1:
  197.     move.l    (a2)+,(a3)+
  198. rowlp1i:
  199.     dbra    d5,rowlp1
  200.     adda.w    d2,a2
  201.     dbra    d7,rowlp0
  202.     bra.s    rowdone
  203. evnlong:    
  204.     move.w    d4,d5
  205.     bra.s    rowlp2i
  206. rowlp2:
  207.     move.l    (a2)+,(a3)+
  208. rowlp2i:
  209.     dbra    d5,rowlp2
  210.     adda.w    d2,a2
  211.     dbra    d7,evnlong
  212. rowdone:
  213.     cmp.w    d0,d1            ;have we become DST form-width?
  214.     bne    scrnchlp        ;iterate until we are DST
  215. *
  216. *   Now copy buffer to last freed area
  217. *
  218. *    a3-> DST tile area just freed
  219. *
  220.     move.l    a5,a2        ;get buffer copied back in
  221. *
  222.     lsl.w    #3,d0        ;DST wrap *8 is # of words in buffer
  223.     mulu    8+2(sp),d0
  224.     bra.s    bufini
  225. bufinlp:
  226.     move.w    (a2)+,(a3)+
  227. bufini:
  228.     dbra    d0,bufinlp
  229. *
  230.     movem.l    (sp)+,a0-a6/d0-d7
  231.     rts
  232. *
  233. *   Rotate 90 degrees clockwise a large square page-size form in place
  234. *
  235. *   Programmer: Dave Staugas
  236. *         Date: 5-June-89
  237. *
  238. *   Entry:
  239. *
  240. *   a0   -> base address of square form to rotate
  241. *   d0.w =  form-width in bytes (must be even)
  242. *   d4.w =  # of bytes on a side of the square (also must be even)
  243. *
  244. *   Exit:
  245. *
  246. *  all regs preserved, square form is rotated in place 90 degrees clockwise
  247. *
  248. roto:
  249.     movem.l    a0-a6/d0-d7,-(sp)
  250.     move.w    d0,d7        ;copy form-width to d7
  251.     lsl.w    #4,d7        ;x16 for offset in form for 1 tile down
  252. *
  253.     lsr.w    #1,d4        ;d4 = # tiles on a side
  254. *
  255. *   a2 -> top/left tile address
  256. *
  257. *   d0 = form-wrap
  258. *   d4 = # of tiles on a side
  259. *   d7 = offset in form for 1 tile down
  260. *
  261. rotlp0:
  262.     move.l    a0,a2        ;a2 -> top/left tile
  263.     move.w    d4,d3
  264.     subq.w    #1,d3
  265.     mulu    d7,d3
  266.     lea    (a2,d3.l),a4    ;a4 -> bot/left tile
  267.     add.w    d4,d4
  268.     lea    -2(a2,d4.w),a3    ;a3 -> top/right tile
  269.     lea    -2(a4,d4.w),a5    ;a5 -> bot/right tile
  270.     lsr.w    #1,d4
  271. rotlp1:
  272.     move.l    a2,a1        ;top/left is SRC
  273.     moveq    #2,d1        ;DST form wrap (just 16 byte buffer)
  274.     lea    tilebuf,a6
  275.     bsr    rot2tile    ;rotate top/left to buffer
  276. *
  277.     move.l    a4,a1        ;bot/left is SRC
  278.     move.w    d0,d1        ;DST form wrap is same as SRC
  279.     move.l    a2,a6        ;top/left is DST
  280.     bsr    rot2tile    ;rotate bot/left to top/left tile
  281. *    
  282.     move.l    a5,a1        ;bot/right is SRC
  283.     move.l    a4,a6        ;bot/left is DST
  284.     bsr    rot2tile    ;rotate bot/right to bot/left tile
  285. *
  286.     move.l    a3,a1        ;top/right is SRC
  287.     move.l    a5,a6        ;bot/right is DST
  288.     bsr    rot2tile    ;rotate top/right to bot/right
  289. *
  290.     lea    tilebuf,a1
  291.     move.l    a3,a6
  292.     moveq    #15,d5
  293. coploop:
  294.     move.w    (a1)+,(a6)
  295.     adda.w    d0,a6
  296.     dbra    d5,coploop    ;copy rotated tile buffer to top/left
  297. *
  298.     adda.w    d7,a2        ;move top/left down 1 tile
  299.     suba.w    d7,a5        ;move bot/right up 1 tile
  300.     addq.l    #2,a4        ;move bot/left right 1 tile
  301.     subq.l    #2,a3        ;move top/right left 1 tile
  302.     cmp.l    a0,a3        ;does top/right equal base?
  303.     bne    rotlp1        ;iterate until it does
  304. *
  305.     lea    2(a0,d7.w),a0    ;now put base down 1 tile & left 1 tile
  306.     subq.l    #2,d4        ;next # of tiles on a side
  307.     beq.s    rotdone        ;br if none left
  308.     cmpi.w    #1,d4        ;check for odd case
  309.     bne    rotlp0
  310. *
  311.     move.l    a0,a1
  312.     move.l    a0,a6
  313.     bsr    rot2tile
  314. *
  315. rotdone:
  316.     movem.l    (sp)+,a0-a6/d0-d7
  317.     rts
  318. *
  319. *
  320. *
  321. *
  322. *    
  323. ******************************************
  324. *
  325. *   Rotate a 16x16 pixel tile clockwise 90 degrees and copy to another tile
  326. *
  327. *
  328. *   d0 = SRC form-wrap
  329. *   d1 = DST form-wrap
  330. *
  331. *   a1 -> top/left of SRC tile
  332. *   a6 -> top/left of DST tile
  333. *  
  334. rot2tile:
  335.     movem.l    a0/a2-a5/d0-d1/d4/d7,-(sp)
  336. *
  337. *  pack 16 words of tile into 4 data & 4 address registers..
  338. *
  339.     move.w    (a1),d2
  340.     adda.w    d0,a1
  341.     move.w    (a1),d3
  342.     adda.w    d0,a1
  343.     move.w    (a1),d4
  344.     adda.w    d0,a1
  345.     move.w    (a1),d5
  346.     adda.w    d0,a1
  347. *
  348.     swap    d2
  349.     swap    d3
  350.     swap    d4
  351.     swap    d5
  352. *
  353.     move.w    (a1),d2
  354.     adda.w    d0,a1
  355.     move.w    (a1),d3
  356.     adda.w    d0,a1
  357.     move.w    (a1),d4
  358.     adda.w    d0,a1
  359.     move.w    (a1),d5
  360.     adda.w    d0,a1
  361. *
  362.     exg    d2,a2
  363.     exg    d3,a3
  364.     exg    d4,a4
  365.     exg    d5,a5
  366. *
  367.     move.w    (a1),d2
  368.     adda.w    d0,a1
  369.     move.w    (a1),d3
  370.     adda.w    d0,a1
  371.     move.w    (a1),d4
  372.     adda.w    d0,a1
  373.     move.w    (a1),d5
  374.     adda.w    d0,a1
  375. *
  376.     swap    d2
  377.     swap    d3
  378.     swap    d4
  379.     swap    d5
  380. *
  381.     move.w    (a1),d2
  382.     adda.w    d0,a1
  383.     move.w    (a1),d3
  384.     adda.w    d0,a1
  385.     move.w    (a1),d4
  386.     adda.w    d0,a1
  387.     move.w    (a1),d5
  388. *
  389. *   Got all 16 words of tile in registers, now rotate..
  390. *
  391.     moveq    #3,d0        ;iterate 4 times
  392. rotlp2:
  393.     swap    d1        ;DST form-width to high word
  394.     swap    d0        ;get d0.w ready to receive bits
  395.     add.w    d5,d5
  396.     addx.w    d1,d1
  397.     add.w    d5,d5
  398.     addx.w    d0,d0
  399.     add.w    d5,d5
  400.     addx.w    d6,d6
  401.     add.w    d5,d5
  402.     addx.w    d7,d7
  403.  
  404.     add.w    d4,d4
  405.     addx.w    d1,d1
  406.     add.w    d4,d4
  407.     addx.w    d0,d0
  408.     add.w    d4,d4
  409.     addx.w    d6,d6
  410.     add.w    d4,d4
  411.     addx.w    d7,d7
  412.  
  413.     add.w    d3,d3
  414.     addx.w    d1,d1
  415.     add.w    d3,d3
  416.     addx.w    d0,d0
  417.     add.w    d3,d3
  418.     addx.w    d6,d6
  419.     add.w    d3,d3
  420.     addx.w    d7,d7
  421.  
  422.     add.w    d2,d2
  423.     addx.w    d1,d1
  424.     add.w    d2,d2
  425.     addx.w    d0,d0
  426.     add.w    d2,d2
  427.     addx.w    d6,d6
  428.     add.w    d2,d2
  429.     addx.w    d7,d7
  430. *
  431.     swap    d2
  432.     swap    d3
  433.     swap    d4
  434.     swap    d5
  435. *
  436.     add.w    d5,d5
  437.     addx.w    d1,d1
  438.     add.w    d5,d5
  439.     addx.w    d0,d0
  440.     add.w    d5,d5
  441.     addx.w    d6,d6
  442.     add.w    d5,d5
  443.     addx.w    d7,d7
  444.  
  445.     add.w    d4,d4
  446.     addx.w    d1,d1
  447.     add.w    d4,d4
  448.     addx.w    d0,d0
  449.     add.w    d4,d4
  450.     addx.w    d6,d6
  451.     add.w    d4,d4
  452.     addx.w    d7,d7
  453.  
  454.     add.w    d3,d3
  455.     addx.w    d1,d1
  456.     add.w    d3,d3
  457.     addx.w    d0,d0
  458.     add.w    d3,d3
  459.     addx.w    d6,d6
  460.     add.w    d3,d3
  461.     addx.w    d7,d7
  462.  
  463.     add.w    d2,d2
  464.     addx.w    d1,d1
  465.     add.w    d2,d2
  466.     addx.w    d0,d0
  467.     add.w    d2,d2
  468.     addx.w    d6,d6
  469.     add.w    d2,d2
  470.     addx.w    d7,d7
  471. *
  472.     swap    d2
  473.     swap    d3
  474.     swap    d4
  475.     swap    d5
  476. *
  477.     exg    d2,a2
  478.     exg    d3,a3
  479.     exg    d4,a4
  480.     exg    d5,a5
  481. *
  482. *
  483.     add.w    d5,d5
  484.     addx.w    d1,d1
  485.     add.w    d5,d5
  486.     addx.w    d0,d0
  487.     add.w    d5,d5
  488.     addx.w    d6,d6
  489.     add.w    d5,d5
  490.     addx.w    d7,d7
  491.  
  492.     add.w    d4,d4
  493.     addx.w    d1,d1
  494.     add.w    d4,d4
  495.     addx.w    d0,d0
  496.     add.w    d4,d4
  497.     addx.w    d6,d6
  498.     add.w    d4,d4
  499.     addx.w    d7,d7
  500.  
  501.     add.w    d3,d3
  502.     addx.w    d1,d1
  503.     add.w    d3,d3
  504.     addx.w    d0,d0
  505.     add.w    d3,d3
  506.     addx.w    d6,d6
  507.     add.w    d3,d3
  508.     addx.w    d7,d7
  509.  
  510.     add.w    d2,d2
  511.     addx.w    d1,d1
  512.     add.w    d2,d2
  513.     addx.w    d0,d0
  514.     add.w    d2,d2
  515.     addx.w    d6,d6
  516.     add.w    d2,d2
  517.     addx.w    d7,d7
  518. *
  519. *
  520.     swap    d2
  521.     swap    d3
  522.     swap    d4
  523.     swap    d5
  524. *
  525.  
  526.     add.w    d5,d5
  527.     addx.w    d1,d1
  528.     add.w    d5,d5
  529.     addx.w    d0,d0
  530.     add.w    d5,d5
  531.     addx.w    d6,d6
  532.     add.w    d5,d5
  533.     addx.w    d7,d7
  534.  
  535.     add.w    d4,d4
  536.     addx.w    d1,d1
  537.     add.w    d4,d4
  538.     addx.w    d0,d0
  539.     add.w    d4,d4
  540.     addx.w    d6,d6
  541.     add.w    d4,d4
  542.     addx.w    d7,d7
  543.  
  544.     add.w    d3,d3
  545.     addx.w    d1,d1
  546.     add.w    d3,d3
  547.     addx.w    d0,d0
  548.     add.w    d3,d3
  549.     addx.w    d6,d6
  550.     add.w    d3,d3
  551.     addx.w    d7,d7
  552.  
  553.     add.w    d2,d2
  554.     addx.w    d1,d1
  555.     add.w    d2,d2
  556.     addx.w    d0,d0
  557.     add.w    d2,d2
  558.     addx.w    d6,d6
  559.     add.w    d2,d2
  560.     addx.w    d7,d7
  561. *
  562.     swap    d2
  563.     swap    d3
  564.     swap    d4
  565.     swap    d5
  566. *
  567.     exg    d2,a2
  568.     exg    d3,a3
  569.     exg    d4,a4
  570.     exg    d5,a5
  571. *
  572.     move.w    d1,(a6)
  573.     swap    d1        ;get DST form-width
  574.     adda.w    d1,a6
  575.     move.w    d0,(a6)
  576.     swap    d0        ;get loop count
  577.     adda.w    d1,a6
  578.     move.w    d6,(a6)
  579.     adda.w    d1,a6
  580.     move.w    d7,(a6)
  581.     adda.w    d1,a6
  582. *
  583.     dbra    d0,rotlp2    ;do all 16
  584. *
  585.     movem.l    (sp)+,a0/a2-a5/d0-d1/d4/d7
  586.     rts
  587. *
  588. *
  589.     .bss
  590. tilebuf:
  591.     .ds.w    16
  592.